from bank_manage_system.admin.deposit_manager import DepositManager
from bank_manage_system.database.db_connector import DatabaseConnector
import logging
import hashlib


class ClientOperations:
    def __init__(self, db: DatabaseConnector, card_id: str):
        self.db = db
        self.card_id = card_id
        self.logger = logging.getLogger(__name__)

    def authenticate(self, password: str) -> bool:
        """密码验证"""
        # 检查密码（假设密码已加密存储）
        hashed_pwd = hashlib.sha256(password.encode()).hexdigest()
        result = self.db.execute_query(
            "SELECT COUNT(*) AS cnt FROM cardinfo WHERE cardID = %s AND pass = %s",
            (self.card_id, hashed_pwd)
        )
        return bool(result and result[0]['cnt'] > 0)

    def get_balance(self) -> float:
        """获取余额"""
        result = self.db.execute_query(
            "SELECT balance FROM cardinfo WHERE cardID = %s",
            (self.card_id,)
        )
        return float(result[0]['balance']) if result else 0.0

    def get_transactions(self, limit: int = 10) -> list:
        """获取交易记录"""
        # 使用视图获取友好显示
        query = """
        SELECT * FROM transactionhistory
        WHERE 卡号 = %s
        ORDER BY 交易类型 DESC
        LIMIT %s
        """
        return self.db.execute_query(query, (self.card_id, limit))

    def deposit(self, amount: float) -> dict:
        """存款（通过调用存款业务）"""
        deposit_manager = DepositManager(self.db)
        return deposit_manager.add_deposit(self.card_id, amount)

    def withdraw(self, amount: float) -> dict:
        """取款（通过调用存款操作的负值）"""
        # 先检查余额
        balance = self.get_balance()
        if balance < amount:
            return {"success": False, "message": "余额不足"}

        # 使用存款操作取负值（触发器会处理）
        return self.deposit(-amount)

    def report_loss(self) -> dict:
        """挂失"""
        try:
            # 更新挂失状态（触发器记录操作）
            self.db.execute_query(
                "UPDATE cardinfo SET isReportLoss = TRUE WHERE cardID = %s",
                (self.card_id,)
            )
            return {"success": True, "message": "挂失成功"}
        except Exception as e:
            return {"success": False, "message": f"挂失失败: {str(e)}"}

    def change_password(self, old_password: str, new_password: str) -> dict:
        """修改密码"""
        if not self.authenticate(old_password):
            return {"success": False, "message": "原密码错误"}

        # 生成新密码的哈希
        new_hashed = hashlib.sha256(new_password.encode()).hexdigest()

        try:
            self.db.execute_query(
                "UPDATE cardinfo SET pass = %s WHERE cardID = %s",
                (new_hashed, self.card_id)
            )
            return {"success": True, "message": "密码修改成功"}

        except Exception as e:
            return {"success": False, "message": f"修改失败: {str(e)}"}

    def transfer(self, target_card_id, amount):
        try:
            # 添加输出参数占位符
            args = (self.card_id, target_card_id, amount, None)  # 第4个参数为输出占位
            # 调用专用方法处理转账
            return self.execute_transfer_procedure(args)
        except Exception as e:
            self.logger.error(f"转账异常: {str(e)}")
            return {'success': False, 'message': '系统错误'}

    """转账专用存储过程调用方法（6.20增）"""

    def execute_transfer_procedure(self, args):
        try:
            with self.db.connection.cursor() as cursor:
                cursor.callproc("TransferFunds", args)
                cursor.execute("SELECT @_TransferFunds_3")
                result_msg = cursor.fetchone()[0]
                self.db.connection.commit()
                return {'success': True, 'message': result_msg}

        except Exception as err:  # 捕获所有异常
            self.logger.error(f"转账存储过程调用失败: {str(err)}")
            if hasattr(self.db, 'connection'):
                self.db.connection.rollback()

            errno = getattr(err, 'errno', None)
            if errno == 1644:
                # 自定义错误消息
                return {'success': False, 'message': str(err)}
            else:
                return {'success': False, 'message': '系统错误，请稍后再试'}


